package ie.lawlor.amvc.event;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class EventPayloadProxyFactory {
    
    Class targetClass;
    EventPayloadProxyMapping mapping;
    public EventPayloadProxyFactory(Class targetClass, EventPayloadProxyMapping mapping){
        this.targetClass = targetClass;
        this.mapping = mapping;
    }
    
    public Object createPayloadProxy(Object sourcePayload){
        Class[] classes = new Class[]{targetClass};
        return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), 
                classes, new MappingInvocationHandler(sourcePayload, mapping));
    }

    private static class MappingInvocationHandler implements InvocationHandler{
        EventPayloadProxyMapping mapping;
        Object sourcePayload;
        
        public MappingInvocationHandler(Object sourcePayload, EventPayloadProxyMapping mapping){
            this.mapping = mapping;
            this.sourcePayload = sourcePayload;
        }

        public Object invoke(Object source, Method targetMethod, Object[] args) throws Throwable {
            String sourceMethodName = mapping.getSourceMethod(targetMethod.getName());
            Class sourceClass = sourcePayload.getClass();
            Class[] argClasses = new Class[]{};
            Method sourceMethod = sourceClass.getMethod(sourceMethodName, argClasses);
            return sourceMethod.invoke(sourcePayload, args);
        }
        
    }
}
